﻿using System;
using System.Data;
using accesoDatos;
using clasesBase;
using System.Collections.Generic;

namespace Logica
{
    public class Usuario : EntidadAlmacenable
    {
        /* --------------------- Atributos de la clase. Recordar que hay atributos heredados --------------------- */
        private string nombre = "";
        private string clave= "";
        private int idRol = 0;
        private Rol objRol;
        private bool deBaja = false;
        private DateTime fechaBaja = ValoresGlobales.FechaMinima;

        private DataTable permisos = null;
        public DataTable Permisos
        {
            get
            {
                if (this.permisos == null)
                {
                    this.permisos = Permiso.listaExtendida(new string[] { "idRol" }, new string[] { "E" + this.idRol.ToString() });
                }
                return this.permisos;
            }
        }

        public const string tablaBD = "usuario", columnaID = "id";


        /* --------------------- Propiedades --------------------- */
        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }

        public string Nombre
        {
            get{ return this.nombre; }
            set{ nombre = value; }

        }

        public string Clave
        {
            get { return this.clave; }
            set { clave = value; }

        }

        public Rol ObjRol
        {
            get { return objRol; }
            set { 
                objRol = value;
                this.idRol = this.objRol.ID;
            }
        }

        public bool DeBaja
        {
            get { return this.deBaja; }
            set { this.deBaja = value; }
        }

        public DateTime FechaBaja
        {
            get { return this.fechaBaja; }
            set { this.fechaBaja = value; }
        }

        /* --------------------- Constructores --------------------- */
        public Usuario()
            : this(0) // Llamo al constructor que recibe un parámetro para reutilizar el código del mismo
        { }

        /* IMPORTANTE:
             ** Si el campo identificador unívoco de la tabla actual tuviese un nombre distinto de "id", se lo debe setear en este momento
             * (atributo heredado: nombreColumnaID)
             ** Si el campo identificador unívoco NO se generase automáticamente, se lo debe definir en este momento, cambiando el atributo
             * heredado idAutoGenerado por FALSE.
             */
        public Usuario(int idElem)
            : base() // Llamo al constructor padre en primer lugar, para inicializar los valores correspondientes
        {
            // Es importante esta asignación ya que estos valores se utilizan tanto en métodos del objeto padre como éste
            this.nombreTablaBD = tablaBD;
            this.nombreColumnaID = columnaID;
            this.id = idElem;

            // Si se hubiese enviado un id != 0, entonces se buscan los datos del elemento en la BD para cargarlos al objeto actual que se está creando
            if (this.id != 0)
            {
                DataRow elemento = this.buscarElemento(id);
                try
                {
                    if (elemento != null)
                    {
                        this.nombre = elemento["nombre"].ToString().Trim();
                        this.clave = elemento["clave"].ToString().Trim();
                        this.idRol = Convert.ToInt32(elemento["idRol"]);
                        this.deBaja = Convert.ToBoolean(elemento["deBaja"]);
                        this.fechaBaja = elemento["fechaBaja"] != DBNull.Value ? Convert.ToDateTime(elemento["fechaBaja"]) : ValoresGlobales.FechaMinima;
                    }
                }
                catch (Exception ex)
                {
                    this.error = ex.Message;
                }
            }

            this.objRol = new Rol(this.idRol);
        }


        /* --------------------- Métodos --------------------- */
        public static DataTable listaExtendida(string[] columnasFiltros, string[] valoresFiltros)
        {
            string camposConsulta = string.Format("{0}.*, {1}.nombre as Rol", tablaBD, Rol.tablaBD);
            string[] tablasJoin = new string[] { string.Format("join {1} on {0}.idRol = {1}.{2}", tablaBD, Rol.tablaBD, Rol.columnaID) };

            ManejadorBD manejador = new ManejadorBD();
            DataSet conjuntoDatos = manejador.obtenerDatos(camposConsulta, tablaBD, tablasJoin, columnasFiltros, valoresFiltros, new string[] { });

            DataTable datosListado;
            if (conjuntoDatos.Tables.Count > 0) datosListado = conjuntoDatos.Tables[0];
            else datosListado = new DataTable("Tabla");

            return datosListado;
        }

        /* Si se encuentra el usuario buscado (según nombre y clave), se devuelve el IDENTIFICADOR del mismo en el sistema.
         * Si no se lo encuentra, devuelve 0. */
        public static int logueo_correcto(string usuario, string clave)
        {
            string clave_encriptada = Seguridad.encriptar(clave);
            string sentenciaSQL = string.Format("SELECT id FROM {0} WHERE nombre = '{1}' AND clave = '{2}' AND deBaja = 0",
                                                Usuario.tablaBD,
                                                usuario,
                                                clave_encriptada);

            ManejadorBD manejador = new ManejadorBD();
            int id_usuario = manejador.obtenerNumeroEntero(sentenciaSQL);

            return id_usuario;
        }

        public String guardar()
        {
            this.clave = Seguridad.encriptar(this.clave);

            String[] columnas = new String[] { columnaID, "nombre", "clave", "idRol", "deBaja", "fechaBaja" };
            String[] valores = new String[] { this.id.ToString(), this.nombre.ToString(), this.clave.ToString(), this.idRol.ToString(), 
                Validador.formatearBool(this.deBaja), Validador.formatearFecha(this.fechaBaja) };

            return base.guardarElemento(columnas, valores);
        }
    }
}
